package com.svms.save.services;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import com.svms.save.entitys.SvdaTsgl;
import com.svms.save.mapper.SvdaTsglMapper;
import com.svms.save.utils.DateUtils;
import com.svms.save.utils.SysCode;

public abstract class BookISBNService {
	/**请求的服务地址为中国国家图书馆*/
	public static final String OPAC_NLC = "opac.nlc";

	Logger log = LoggerFactory.getLogger(BookISBNService.class);
	@Autowired
	private RestTemplate restTemplate;
	@Autowired
	private SvdaTsglMapper tsglMapper;
	
	@Transactional
	public int doSaveTsgl(List<SvdaTsgl> tsgls) {
		int r = 0;
		if(null != tsgls && tsgls.size() > 0) {
			for(SvdaTsgl tsgl : tsgls) {
				tsgl.setCzsj(DateUtils.doFormatDate(new Date(), SysCode.DATESTR_FORMATTER_L));
				if(null != tsgl.getObjectid()) {
					r += tsglMapper.updateByPrimaryKey(tsgl);
				}else {
					r +=tsglMapper.insert(tsgl);
				}
			}
		}
		return r;
	}

	/**
	 * 根据isbn码查询书籍
	 * 
	 * @param atServer
	 * @param isbn
	 * @return
	 */
	public List<SvdaTsgl> findByISBN(String atServer, String isbn) throws Exception {
		List<SvdaTsgl> list = null;
		if(OPAC_NLC.equals(atServer)) {
			list = findTsxxByZGGJTS(isbn);
		}
		return list;
	}
	/**
	 * 获取查询URL授权后的地址
	 * @return
	 */
	private String findSearchUrl() {
		String res = "";
		String sendSearchUrl = "http://opac.nlc.cn/F";
		String respBody = restTemplate.getForObject(sendSearchUrl, String.class);
		String selector = "form[name='form1']";
		if (StringUtils.isNotBlank(respBody)) {
			Document doc = this.parseDoc(respBody);
			Elements els = doc.select(selector);
			if (null != els) {
				if (els.iterator().hasNext()) {
					Element atTab = els.iterator().next();
					res = atTab.attr("action");
				}else {
					log.error("findSearchUrl未获取到【{}】元素！",selector);
				}
			}else {
				log.error("findSearchUrl未获取到【{}】元素！",selector);
			}
		}else {
			log.error("findSearchUrl请求结果为空！");
		}
		return res;
	}
	
	private String getPageBaseUrl(Document doc) {
		String url = null;
		try {
			Element navScriptEl = doc.select("div[id='nav'] script").get(0);
			String scriptText = navScriptEl.toString();
			int sIdx = scriptText.indexOf("http://");
			int lIdx = scriptText.lastIndexOf("&jump=");
			url = scriptText.substring(sIdx,lIdx);
		}catch (Exception e) {
			// TODO: handle exception
			log.error("获取分页跳转基础URL失败！",e);
		}
		return url;
	}
	/**
	 * 在中国国家图书网站中根据ISBN查询书籍信息
	 * 
	 * @param isbn
	 * @return
	 */
	private List<SvdaTsgl> findTsxxByZGGJTS(String isbn) {
		List<SvdaTsgl> list = null;
		if (StringUtils.isBlank(isbn)) {
			return null;
		}
		String selector = "table[id='td']";
		String selector_hitnum = "div[id='hitnum']";
		String toUrl = findSearchUrl();
//		String sendURL = toUrl + "?func=find-b&find_code=ISB&request="
//				+ isbn
//				+ "&local_base=NLC01&filter_code_1=WLN&filter_request_1=&filter_code_2=WYR&filter_request_2=&filter_code_3=WYR&filter_request_3=&filter_code_4=WFM&filter_request_4=&filter_code_5=WSL&filter_request_5=";
		String sendURL = toUrl +"?find_base=NLC01&find_base=NLC09&func=find-m&find_code=ISB&request="+isbn+"&local_base=&filter_code_1=WLN&filter_request_1=&filter_code_2=WYR&filter_request_2=&filter_code_3=WYR&filter_request_3=&filter_code_4=WFM&filter_request_4=&filter_code_5=WSL&filter_request_5=";
		log.info("中国国家图书网站【{}】......", sendURL);
		String respBody = restTemplate.getForObject(sendURL, String.class);
		if (StringUtils.isNotBlank(respBody)) {
			Document doc = this.parseDoc(respBody);
			Elements elsTD = doc.select(selector);
			Elements elsHitnum = doc.select(selector_hitnum);
			if (null != elsTD && elsTD.iterator().hasNext()) {
				SvdaTsgl tsxx = findDetail(elsTD);
				if(null != tsxx) {
					list = new ArrayList<SvdaTsgl>();
					list.add(tsxx);
				}
			} else if(null != elsHitnum && elsHitnum.iterator().hasNext()){
				list = findList(doc, elsHitnum);
			}else {
				log.error("未获取指定内容【{}】！", selector);
				return null;
			}
		} else {
			log.error("请求结果为空！");
		}
		return list;
	}
	private List<SvdaTsgl> findList(Document doc,Elements els){
		List<SvdaTsgl> allList = new ArrayList<SvdaTsgl>();
		int pageSize = 10;
		int pageNo = 1;
		Element hitnumEl = els.iterator().next();
		String hitnumtext = hitnumEl.text();
		hitnumtext = hitnumtext.replace(" ", "");
		int sIdx = hitnumtext.indexOf("of");
		int eIdx = hitnumtext.indexOf("(最");
		if(sIdx > -1) {
			sIdx = sIdx +2;
		}
		int count = -1;
		String countStr = hitnumtext.substring(sIdx, eIdx);
		try {
			count = Integer.parseInt(countStr);
		}catch(Exception e) {
			log.error("获取总数据条数转换INT错误！",e);
		}
		if(count > pageSize) {
			pageNo = count / pageSize;
			if((count % pageSize) > 0) {
				pageNo++;
			}
		}
		//首页第一页
		List<SvdaTsgl> list = this.toList(doc);
		if(null != list) {
			allList.addAll(list);
		}
		//其他页数据
		if(pageNo > 1) {
			String jumpUrl = "&jump=";
			String baseUrl = this.getPageBaseUrl(doc);
			if(StringUtils.isNotBlank(baseUrl)) {
				for(int i=2;i<=pageNo;i++) {
					int jumpno = pageSize * (i - 1) + 1;
					String sendUrl = baseUrl + jumpUrl + jumpno;
					String respBody = restTemplate.getForObject(sendUrl, String.class);
					if (StringUtils.isNotBlank(respBody)) {
						Document docNP = this.parseDoc(respBody);
						List<SvdaTsgl> npList = this.toList(docNP);
						if(null != npList) {
							allList.addAll(npList);
						}
						baseUrl = this.getPageBaseUrl(docNP);
					}
				}
			}
		}
		return allList;
	}
	
	private List<SvdaTsgl> toList(Document doc){
		List<SvdaTsgl> list = null;
		String selectorItems = "table[class='items']";
		Elements elts = doc.select(selectorItems);
		if(null != elts && elts.iterator().hasNext()) {
			list = new ArrayList<SvdaTsgl>();
			Iterator<Element> elIts = elts.iterator();
			while(elIts.hasNext()) {
				SvdaTsgl item = new SvdaTsgl();
				Element el = elIts.next();
				Element elTr = el.select("tr").get(0);
				Element elTd = elTr.select("td").get(2);
				Element titleEl = elTd.select("div[class='itemtitle'] a").get(0);
				String tmyzz = titleEl.text();
				if (StringUtils.isNotBlank(tmyzz)) {
					String[] tmyzzSplit = tmyzz.split("/");
					String tm = tmyzzSplit[0];
					tm = tm.replace(" ", "");
					tm = tm.replace("[专著]", "");
					item.setSjmc(tm);
				}
				Element detailEl = elTd.select("table").get(0);
				Element detailTrEl = detailEl.select("tr").get(0);
				Elements detailTdEls = detailTrEl.select("td");
				Element zzEl = detailTdEls.get(1);
				Element cbsEl = detailTdEls.get(3);
				String zz = zzEl.text();
				String cbs = cbsEl.text();
				if (StringUtils.isNotBlank(zz)) {
					String nzz = zz.replace(" ", "");
					item.setSjzz(nzz);
				}
				if (StringUtils.isNotBlank(cbs)) {
					String ncbs = cbs.replace(" ", "");
					item.setCbs(ncbs);
				}
				list.add(item);
			}
		}
		return list;
	}

	private SvdaTsgl findDetail(Elements els) {
		SvdaTsgl tsxx = null;
		Element atTab = els.iterator().next();
		log.info("详情TABLE区域报文【{}】......", atTab.html());
		Elements trs = atTab.select("tr");
		if (trs.size() > 4) {
			tsxx = new SvdaTsgl();
			Element tmyzrTr = trs.get(3);
			Element cbsTr = trs.get(4);
			Element bzTr = trs.get(9);
			Element zzTr = trs.get(11);
			// 题名与责任
			Elements tmyzrTds = tmyzrTr.select("td");
			// 出版社和年份
			Elements cbsTds = cbsTr.select("td");
			// 备注
			Elements bzTds = bzTr.select("td");
			// 作者
			Elements zzTds = zzTr.select("td");
			String tmyzz = this.getContentText(tmyzrTds, 1);
			String cbs = this.getContentText(cbsTds, 1);
			String bz = this.getContentText(bzTds, 1);
			String zz = this.getContentText(zzTds, 1);
			if (StringUtils.isNotBlank(tmyzz)) {
				String[] tmyzzSplit = tmyzz.split("/");
				String tm = tmyzzSplit[0];
				tm = tm.replace(" ", "");
				tm = tm.replace("[专著]", "");
				tsxx.setSjmc(tm);
			}
			if (StringUtils.isNotBlank(cbs)) {
				String ncbs = cbs.replace(" ", "");
				tsxx.setCbs(ncbs);
			}
			if (StringUtils.isNotBlank(bz)) {
				String nbz = bz.replace(" ", "");
				tsxx.setSjbz(nbz);
			}
			if (StringUtils.isNotBlank(zz)) {
				String nzz = zz.replace(" ", "");
				tsxx.setSjzz(nzz);
			}
		}
		return tsxx;
	}

	private String getContentText(Elements els, int idx) {
		if (null != els && els.size() >= (idx + 1)) {
			Element el = els.get(idx);
			return el.text();
		}
		return "";
	}

	public Document parseDoc(String content) {
		// TODO Auto-generated method stub
		Document doc = Jsoup.parseBodyFragment(content);
		return doc;
	}
}
